package org.giovanolli.mumi.filter;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;

import com.samaxes.filter.util.CacheConfigParameter;
import com.samaxes.filter.util.Cacheability;
import com.samaxes.filter.util.HTTPCacheHeader;

/**
 * The Class CustomFilter.
 */
public class CustomFilter implements Filter {

	/** The cached files. */
	private List<String> cachedFiles;

	/** The cacheability. */
	private Cacheability cacheability;

	/** The is static. */
	private boolean isStatic;

	/** The seconds. */
	private long seconds;

	/* (non-Javadoc)
	 * @see javax.servlet.Filter#destroy()
	 */
	@Override
	public void destroy() {
	}

	/* (non-Javadoc)
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
		HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
		String path = ((javax.servlet.http.HttpServletRequest) servletRequest).getPathInfo();

		String pathExtension = "";
		if (path.lastIndexOf(".") > -1) {
			pathExtension = path.substring(path.lastIndexOf(".") + 1);
		}
		if (cachedFiles.contains(pathExtension)) {
			StringBuilder cacheControl = new StringBuilder(cacheability.getValue()).append(", max-age=").append(seconds);

			if (!isStatic) {
				cacheControl.append(", must-revalidate");
			}

			// Set cache directives
			httpServletResponse.setHeader(HTTPCacheHeader.CACHE_CONTROL.getName(), cacheControl.toString());
			httpServletResponse.setDateHeader(HTTPCacheHeader.EXPIRES.getName(), System.currentTimeMillis() + seconds * 1000L);

			/*
			 * By default, some servers (e.g. Tomcat) will set headers on any SSL content to deny caching. Setting the Pragma header to null or to an empty string takes care of
			 * user-agents implementing HTTP 1.0.
			 */
			if (httpServletResponse.containsHeader("Pragma")) {
				httpServletResponse.setHeader(HTTPCacheHeader.PRAGMA.getName(), null);
			}
		} else {
			// set cache directives
			httpServletResponse.setHeader(HTTPCacheHeader.CACHE_CONTROL.getName(), "no-cache, no-store, must-revalidate");
			httpServletResponse.setDateHeader(HTTPCacheHeader.EXPIRES.getName(), 0L);

		}
		filterChain.doFilter(servletRequest, servletResponse);
	}

	/* (non-Javadoc)
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
	 */
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		cacheability = (Boolean.valueOf(filterConfig.getInitParameter(CacheConfigParameter.PRIVATE.getName()))) ? Cacheability.PRIVATE : Cacheability.PUBLIC;
		isStatic = Boolean.valueOf(filterConfig.getInitParameter(CacheConfigParameter.STATIC.getName()));

		String cachedFilesParam = filterConfig.getInitParameter("cachedFiles");

		if (cachedFilesParam != null && !StringUtils.isEmpty(cachedFilesParam)) {
			cachedFiles = Arrays.asList(cachedFilesParam.split(","));
		}

		try {
			seconds = Long.valueOf(filterConfig.getInitParameter(CacheConfigParameter.EXPIRATION_TIME.getName()));
		} catch (NumberFormatException e) {
			throw new ServletException(new StringBuilder("The initialization parameter ").append(CacheConfigParameter.EXPIRATION_TIME.getName()).append(" is missing for filter ")
			        .append(filterConfig.getFilterName()).append(".").toString());
		}

	}
}
